﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Common.Entitys;
using Common.Entitys.CommonLogs;
using Common.Entitys.Messages;
using Common.Utlis;
using Common.Utlis.Extend;

namespace Common.Utils.IPCHelps
{
    public class IPCServer
    {

        private TcpServerHelp m_TcpServerHelp = new TcpServerHelp();

        /// <summary>
        /// 进程间通讯的缓存(类型缓存)
        /// </summary>
        public ConcurrentQueue<object> m_IPCObjCache = new ConcurrentQueue<object>();

        /// <summary>
        /// 进程间通讯的缓存(数据缓存)
        /// </summary>
        public ConcurrentQueue<Byte[]> m_IPCBytesCache = new ConcurrentQueue<Byte[]>();

        public IPCServer()
        {
            MessageAggregator<IPCMsg>.Subscribe(OnIPCMsg);
        }

        private void OnIPCMsg(IPCMsg ipcMsg)
        {
            m_IPCObjCache.Enqueue(ipcMsg);
        }

        public void Init(string serverIP, int port)
        {
            Task.Factory.StartNew(DealSend, TaskCreationOptions.LongRunning);
            Task.Factory.StartNew(DealReceive, TaskCreationOptions.LongRunning);
            //发送心跳包
            m_TcpServerHelp.IsSendHeartMsg = true;
            m_TcpServerHelp.Init(serverIP, port);
            m_TcpServerHelp.ReceiveAction += this.DealReceive;
        }

        public bool IsSendAll()
        {
            return m_IPCObjCache.IsEmpty;
        }



        private void DealSend()
        {
            while (true)
            {
                try
                {

                    if (!m_IPCObjCache.TryDequeue(out object entity))
                    {
                        Thread.Sleep(50);
                        continue;
                    }

                    SendObject(entity);
                    // m_TcpServerHelp.SendBytes(IPCCommon.GetEntityByte(entity));
                }
                catch (Exception)
                {

                }
            }
        }

        /// <summary>
        /// 发送添加日志
        /// </summary>
        /// <param name="entity"></param>
        private void SendObject(object entity)
        {
            if (entity is byte[] valueBytes)
            {
                m_TcpServerHelp.SendBytes(valueBytes);
            }
            else
            {
                m_TcpServerHelp.SendBytes(IPCCommon.GetEntityByte(entity));
            }
        }

        private void DealReceive()
        {
            byte[] lastBytes = null;
            bool canNextDeal = false;
            while (true)
            {
                try
                {
                    if (canNextDeal == false)
                    {
                        if (!m_IPCBytesCache.TryDequeue(out byte[] bytes))
                        {
                            Thread.Sleep(50);
                            continue;
                        }

                        if (lastBytes == null)
                        {
                            //上次处理没有剩余
                            lastBytes = GetLastByte(bytes, out canNextDeal);
                        }
                        else
                        {
                            //上次处理有剩余 合并剩余的数组和当前数组
                            Byte[] dealBytes = lastBytes.Mergin(ref bytes);
                            lastBytes = GetLastByte(dealBytes, out canNextDeal);
                        }
                        continue;
                    }
                    else
                    {
                        //上次处理有剩余 合并
                        lastBytes = GetLastByte(lastBytes, out canNextDeal);
                        continue;
                    }
                }
                catch (Exception e)
                {
                    LogHelp.AddLog(new ErrorLogEntity(e));
                }
            }
        }

        private void DealReceive(byte[] bytes)
        {
            m_IPCBytesCache.Enqueue(bytes);
        }

        private byte[] GetLastByte(Byte[] bytes, out bool canNextDeal)
        {
            canNextDeal = false;
            if (bytes.Length < 4)
            {
                return bytes;
            }

            byte[] lengthBytes = bytes.Copy(4);
            //取长度
            int dataLength = BitConverter.ToInt32(lengthBytes, 0);

            int onceLength = dataLength + 4;

            if (onceLength > bytes.Length)
            {
                return bytes;
            }
            byte[] contentBytes = bytes.Copy(4, dataLength);
            try
            {
                Object obj = SerializeHelp.ByteToObj(contentBytes);
                Type messageType = obj.GetType();
                //将收到的消息发送出去
                IPCMsg ipcMsg = obj as IPCMsg;
                DealIPCMsg(ipcMsg);
                //  MessageAggregator.Publish(ipcMsg.Obj, ipcMsg.TypeGuid);
            }
            catch (Exception e)
            {
                LogHelp.WriteLog<ErrorLogEntity>(e);
            }

            if (bytes.Length == onceLength)
            {
                return null;
            }

            byte[] lastBytes = bytes.Copy(onceLength, bytes.Length - onceLength);
            //处理粘包
            canNextDeal = true;
            return lastBytes;
        }

        private void DealIPCMsg(IPCMsg ipcMsg)
        {
            //SelectedViewModel(ipcMsg.Obj, (string)ipcMsg.Obj.GetType().GetProperty("MessageName").GetValue(ipcMsg.Obj));
         //   MessageAggregator<SprinklerMessage>.Publish((SprinklerMessage)ipcMsg.Obj, cc);
             MessageAggregator.Publish(ipcMsg.Obj);
        }
    }
}
